﻿using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.IO;
using CompactMapper.Orm.Contracts;
using CompactMapper.Orm.Queries;

namespace CompactMapper.Orm.UnitOfWork.Mappings
{
    internal class Mappings : IMappings
    {
        private readonly CreationMappings _creationMappings;
        private readonly DeleteMappings _deleteMappings;
        private readonly InsertMappings _insertMappings;
        private readonly QueryMappings _queryMappings;
        private readonly TablesTree _tablesTree;


        internal Mappings(IEnumerable<String> assemblyStrings)
        {
            _tablesTree = new TablesFactory(assemblyStrings).TablesTree;
            _creationMappings = new CreationMappings(_tablesTree);
            _insertMappings = new InsertMappings(_tablesTree);
            _queryMappings = new QueryMappings(_tablesTree);
            _deleteMappings = new DeleteMappings(_tablesTree);
        }


        public void RunCreate(SQLiteConnection connection)
        {
            _creationMappings.Run(connection);
        }

        public IEnumerable<T> RunGetAll<T>(SQLiteConnection connection)
            where T : class
        {
            return RunQuery<T>(connection, Query.Null);
        }

        public IEnumerable<T> RunQuery<T>(SQLiteConnection connection, Query query)
            where T : class
        {
            return _queryMappings.Run<T>(connection, query);
        }

        public void RunInsert(SQLiteConnection connection, IEnumerable<IKeyedPersistent> toInsert)
        {
            _insertMappings.Run(connection, toInsert);
        }

        public void RunDelete<T>(SQLiteConnection connection, IKey toDelete)
            where T : class, IKeyedPersistent
        {
            _deleteMappings.Run<T>(connection, toDelete);
        }

        public void RunDeleteAll<T>(SQLiteConnection connection)
        {
            _deleteMappings.Run<T>(connection);
        }

        public MemoryStream DumpSchema()
        {
            var stream = new MemoryStream();
            _creationMappings.DumpSchema(stream);
            stream.Seek(0, SeekOrigin.Begin);
            return stream;
        }
    }
}